# -*- mode: org; -*-
#+TITLE: LF2 Survival Stage Generator
#+AUTHOR: Zelphir Kaltstahl
#+EMAIL: zelphirkaltstahl@posteo.de
#+STARTUP: content indent align inlineimages hideblocks entitiesplain nologdone nologreschedule nologredeadline nologrefile
#+TODO: TODO WIP DEPRECATED | DONE
#+DATE: <2021-08-01 So>
#+KEYWORDS: lf2 little-fighter-2 survival-stage generator
#+LANGUAGE: English
#+PRIORITIES: A E E
#+EXCLUDE_TAGS: noexport
#+OPTIONS: ^:{}
#+OPTIONS: H:10
#+OPTIONS: toc:2
#+OPTIONS: tags:nil
#+OPTIONS: tasks:t
#+OPTIONS: H:6
#+OPTIONS: p:nil
#+OPTIONS: pri:nil
#+OPTIONS: prop:nil
#+OPTIONS: todo:t
#+OPTIONS: stat:nil
#+OPTIONS: |:t
#+OPTIONS: inline:nil
#+OPTIONS: date:t

* About
:PROPERTIES:
  :CUSTOM_ID: about
  :END:

LF2 Survival Stage Generator is a work-in-progress (WIP) project for generating random survival stages fir Little Fighter 2. There is still a lot of work to be done. For ideas about the planned functionality take a look at =doc/notes.org= or =doc/notes.md=.

The code is written in GNU Guile (=3.0.7=). As far as I know there is no GNU Guile 3.0.7 version for other operating system than GNU/Linux. This means, that in order to use this program, you will likely have to use GNU/Linux.

* Usage
:PROPERTIES:
:CUSTOM_ID: usage
:END:

(project is still work-in-progress)

** Cloning
:PROPERTIES:
:CUSTOM_ID: usage-cloning
:END:

This repository uses git submodules.

#+begin_src shell
git clone git@notabug.org:ZelphirKaltstahl/lf2-data-reader.git
cd lf2-data-reader
git submodule update --init --recursive
#+end_src

** Using GNU Guix
:PROPERTIES:
:CUSTOM_ID: usage-gnu-guix
:END:

With GNU Guix installed, you can do the following:

1. activate the specified GNU Guix environment:

   #+begin_src shell
   bash guix-env/env.sh
   #+end_src

2. run the program:

   #+begin_src shell
   make run
   #+end_src

The output should show a decrypted =stage.dat= file.

** Other ways
:PROPERTIES:
:CUSTOM_ID: usage-other
:END:

All you need is a working GNU Guile installation to run the program. How you get
it, does not really matter. For example you could use your system package to
install GNU Guile, if it is available in your the package sources of your
system, or you could download the source code of GNU Guile and compile it for
your system.

** Interactive REPL session
:PROPERTIES:
:CUSTOM_ID: usage-interactive-repl-session
:END:

Here is an example for an interactive REPL session. Run your REPL from the root directory of this project and then input the following:

#+name: renderer-repl-interaction
#+begin_src scheme
(add-to-load-path ".")
(add-to-load-path "lib")
(add-to-load-path "lib/lf2-data-reader/")
(add-to-load-path "lib/lf2-data-crypt/")
(add-to-load-path "lib/guile-random-utils/")
(load "lib/lf2-data-reader/renderer.scm")

(import
  (except (rnrs base) let-values)
  (only (guile)
        lambda* λ
        error
        eof-object?
        simple-format
        current-output-port
        call-with-output-string
        )
  (prefix (logging) log:)
  (ice-9 binary-ports)
  (ice-9 textual-ports)
  (ice-9 peg)
  (ice-9 pretty-print)
  (print-utils)
  (peg-tree-utils)
  (file-reader)
  (random-utils)
  (prefix (lf2-data-crypt) lf2crypt:)
  (prefix (grammar) grammar:)
  (prefix (srfi srfi-1) srfi-1:))

(load "lib/peg-tree-utils.scm")
(import (renderer))

(define loc "data/stage.dat")
(define stage-text (process-file loc lf2crypt:decrypt))
(define stage-data (peg:tree (match-pattern grammar:STAGE-DAT stage-text)))
(define survival-data (find-in-peg-tree stage-data 'SURVIVAL-STAGE))
(define phases (flatten-filter-peg-tree (find-all-in-peg-tree survival-data 'PHASE) 'PHASE))
(define phase (list-ref phases 0))

(print-limited stage-text #:max 1024)
(print-limited (fisher-yates-shuffle phases)
               #:max 2048)

(render-data (list phase))

;; and perhaps the following is useful too
(load "lib/lf2-data-reader/lib/alist-utils.scm")
(import (lib alist-utils))

(load "lib/lf2-data-reader/model/entity.scm")
(import (model entity))

(define phase-entities
  (alist-item-value (alist-find-item-by-key 'PHASE-ENTITIES (cdr phase))))

(define entity (srfi-1:first phase-entities))

(entity-list-repr->entity entity)
#+end_src

* Testing
:PROPERTIES:
:CUSTOM_ID: testing
:END:

You can run unit tests using the following command:

#+begin_src shell
guile -L . test/<TEST FILE>
#+end_src

Or run tests from submodules, if tests exist.

* Dependencies
:PROPERTIES:
:CUSTOM_ID: dependencies
:END:

The project depends on nothing except GNU Guile. It is tested using GNU Guile
=3.0.7=, but probably works using many older versions as well.

* To do [0/3]
:PROPERTIES:
:CUSTOM_ID: to-do
:END:

+ [ ] write the code for translating back the data structure of a stage to a string
+ [ ] implement replace operation for peg tree
+ [ ] add more tests

* local variables                                                  :noexport:

# Local Variables:
# fill-column: 80
# comment-column: 50
# org-babel-noweb-wrap-start: "<<"
# org-babel-noweb-wrap-end: ">>"
# End:
